import React, { Component } from 'react'
import { inject } from 'mobx-react/index'
import './index.less'
import { CaretDownOutlined } from '@ant-design/icons'
import classnames from 'classnames'
import { Badge, message } from 'antd'
import echarts from 'echarts'
import Mtable from './Table/index'
import getData from '@/Utils/fecth'
import { address } from '@/Utils/apiConfig.js'
import moment from 'moment'
import _ from 'lodash'
const { leagueManagement: { getChannelList }} = address

const { monitor: { queryOverview, recentBlock, recentTx, queryOrgPeer, queryTxhistory }} = address

// 交易
const column1 = [
  {
    title: '交易时间',
    dataIndex: 'timestamp',
    key: 'timestamp',
    width: '128',
  },
  {
    title: 'TxHash',
    dataIndex: 'tx_hash',
    key: 'tx_hash',
    width: '324',
    tooltip: true,
  },
]

// 区块
const column2 = [
  {
    title: '序号',
    dataIndex: 'height',
    key: 'height',
    width: '32',
  },
  {
    title: 'Hash',
    dataIndex: 'data_hash',
    key: 'data_hash',
    width: '191',
    tooltip: true,
  },
  {
    title: '交易数',
    dataIndex: 'tx_number',
    key: 'tx_number',
    width: '48',
  },,
  {
    title: '生成时间',
    dataIndex: 'timestamp',
    key: 'timestamp',
    width: '102',
  },
]

const STATUS = {
  'SUCCESS': '运行中',
  'FAIL': '失败',
}
@inject('SocketModel')
class Monitor extends Component {
  constructor(props) {
    super(props)
    this.state = {
      currentChannel: '',
      channelList: [],
      resultData: null,
      data1Conf: [
        {
          label: '节点总数',
          params: 'nodeNum',
        },
        {
          label: '交易总数',
          params: 'tx_number',
        },
        {
          label: '区块高度',
          params: 'blockNum',
        },
      ],
      data2Conf: [
        {
          label: '链名称',
          params: 'consortiumName',
        },
        {
          label: '网络类型',
          params: 'network',
        },
        {
          label: '共识算法',
          params: 'consensus',
        },
        {
          label: '运行状态',
          params: 'consortiumStatus',
        },
        {
          label: '创建时间',
          params: 'createTime',
        },
      ],
      table1Data: [],
      table2Data: [],
      peerList: [
        {
          id: '11',
          name: 'Peer1',
          type: 'peer',
          parent: '1',
        },
        {
          id: '12',
          name: 'Peer2',
          type: 'peer',
          parent: '1',
        },
        {
          id: '21',
          name: 'Orderer1',
          type: 'orderer',
          parent: '2',
        },
        {
          id: '22',
          name: 'Orderer2',
          type: 'orderer',
          parent: '2',
        },
        {
          id: '31',
          name: 'Orderer3',
          type: 'orderer',
          parent: '3',
        },
        {
          id: '32',
          name: 'Orderer4',
          type: 'orderer',
          parent: '3',
        },
        {
          id: '33',
          name: 'Peer5',
          type: 'peer',
          parent: '3',
        },
        {
          id: '34',
          name: 'Orderer5',
          type: 'orderer',
          parent: '3',
        },
        {
          id: '35',
          name: 'Peer6',
          type: 'peer',
          parent: '3',
        },
      ],
      orgList: [
        {
          id: '1',
          name: 'Org1',
        },
        {
          id: '2',
          name: 'Org2',
        },
        {
          id: '3',
          name: 'Org3',
        },
        {
          id: '4',
          name: 'Org4',
        },
        {
          id: '5',
          name: 'Org5',
        },
      ],
      channelId: '',
      consortiumId: '',
      pageNum: 1,
      pageSize: 5,
      optionFlag: false,
    }
  }

    // 页面缩放
    initScale = () => {
      document.getElementsByTagName('html')[0].style.backgroundColor = '#151E3A'
      document.getElementById('body').style.backgroundColor = '#151E3A'
      const currentWidth = document.documentElement.clientWidth
      const currentHeight = document.documentElement.clientHeight
      const widthPrecent = currentWidth * 1.0 / 1920
      const heightPercent = currentHeight * 1.0 / 1080
      const minPercent = Math.min(widthPrecent, heightPercent)
      const marginLeft = (currentWidth - minPercent * 1920) / 2
      const marginTop = (currentHeight - minPercent * 1080) / 2
      document.getElementById('body').style.width = '1920px'
      document.getElementById('body').style.height = '1080px'
      document.getElementById('body').style.transformOrigin = 'left top'
      document.getElementById('body').style.transform = `scale(${minPercent}) translateZ(0)`
      document.getElementById('body').style.marginTop = `${marginTop}px`
      document.getElementById('body').style.marginLeft = `${marginLeft}px`
    }

    componentDidMount() {
      this.initScale()
      window.addEventListener('resize', this.initScale)

      const url = this.props.location.pathname
      const consortiumId = url.split('/')[2]
      this.setState({
        consortiumId,
      }, () => {
        this.getChannelList()
        this.getTopologyData()
        this.getTxHistory()
      })
    }

    // 获取交易历史
    getTxHistory = () => {
      const { consortiumId } = this.state
      getData().get(queryTxhistory.format({ consortiumId })).then(res => {
        if (res.status === 200) {
          const data = res.data
          let dateArr = [] // 日期
          let dataArr = [] // 数据
          data.forEach(item => {
            dateArr.push(item.date)
            dataArr.push(item.count)
          })
          this.getTransactionHistory(dateArr, dataArr)
        }
      })
    }

    // 获取组织节点信息
    getTopologyData = () => {
      const { consortiumId } = this.state
      getData().get(queryOrgPeer.format({ consortiumId })).then(res => {
        if (res.status === 200) {
          let orgList = res.data
          let peerList = []
          orgList.forEach(item => {
            const list = item.nodes || []
            list.length && peerList.push(...list)
          })
          // 拓扑图 绘制图标
          this.topologyCanvas(peerList, orgList)
        }
      })
    }

    // 交易历史绘图
    getTransactionHistory = (dateArr, dataArr) => {
      // 初始化echarts
      this.myChart = document.getElementById('echarts') && echarts.init(document.getElementById('echarts'))

      const chartOption = {
        grid: {
          left: 44,
          right: 0,
          bottom: 23,
          top: 27,
        },
        textStyle: {
          fontFamily: 'DIN-Regular,DIN',
          color: 'rgba(255,255,255,0.6)',
        },
        xAxis: {
          type: 'category',
          data: dateArr,
          boundaryGap: false,
          axisLine: {
            lineStyle: {
              color: 'rgba(255,255,255,0.04)',
            },
          },
          axisTick: {
            show: false,
          },
        },
        yAxis: {
          type: 'value',
          axisLine: {
            lineStyle: {
              color: 'rgba(255,255,255,0.04)',
            },
          },
          axisTick: {
            show: false,
          },
          splitLine: {
            lineStyle: {
              color: 'rgba(255,255,255,0.04)',
            },
          },
        },
        series: [
          {
            name: '协同工单',
            type: 'line',
            showSymbol: false,
            lineStyle: {
              color: '#0092FF',
            },
            areaStyle: {
              color: {
                type: 'linear',
                x: 0,
                y: 1,
                x2: 0,
                y2: 0,
                colorStops: [{
                  offset: 0, color: 'rgba(0, 254, 231, 0)', // 0% 处的颜色
                }, {
                  offset: 1, color: 'rgba(0, 254, 231, 0.3)', // 100% 处的颜色
                }],
                global: false, // 缺省为 false
              },
            },
            smooth: 0.5,
            itemStyle: {
              color: '#FF7B17',
            },
            data: dataArr,
          },
        ],
      }

      this.myChart.setOption(chartOption)
    }

    // 计算数据
    computerData = (peerList) => {
      var temp = {}
      let arr = []
      for (var i in peerList) {
        var key = peerList[i].parent
        if (temp[key]) {
          temp[key] += 1
        } else {
          temp[key] = 1
        }
      }

      for (var k in temp) {
        if (temp[k] >= 5) {
          arr.push(k)
        }
      }
      return arr
    }

    formatData = (orgList, peerList) => {
      let peerIcon = null
      let orgIcon = require('../../images/monitor/org_big.svg')

      // 记录节点超过3哥的组织
      let tempArr = this.computerData(peerList)

      orgList.map(item => {
        item.itemStyle = null
        item.label = item.name
        item.symbol = `image://${orgIcon}`
        item.symbolSize = [142, 150]
        item.x = item.y = null
        return item
      })
      peerList.map(peer => {
        peer.itemStyle = null
        peer.label = peer.name
        peer.symbolSize = [61, 69]
        peer.x = peer.y = null
        if (peer.type === 'ca') {
          peerIcon = require('../../images/monitor/peer_big.svg')
        } else {
          peerIcon = require('../../images/monitor/orderer_big.svg')
        }
        peer.symbol = `image://${peerIcon}`
        tempArr.forEach(i => {
          if (peer.parent === i) {
            peer.symbolSize = [49, 55]
          } else {
            peer.symbolSize = [61, 69]
          }
        })
        return peer
      })
      return orgList.concat(peerList)
    }

    getLinks = (orgList, peerList) => {
      let links = []
      orgList.map((org, idx) => {
        links.push(
          {
            id: idx,
            source: org.id,
            target: idx + 1 > orgList.length - 1 ? orgList[0].id : orgList[idx + 1].id,
            lineStyle: {
              color: '#0F51C7',
              width: 2,
            },
          }
        )
        return links
      })
      peerList.map((peer, idx) => {
        links.push({
          id: idx,
          source: peer.id,
          target: peer.organization_id,
          lineStyle: {
            color: '#259EB8',
            width: 2,
          },
        })
        return links
      })
      return links
    }

    topologyCanvas = (peerList, orgList) => {
      // 初始化echarts
      this.topologyChart = document.getElementById('topology') && echarts.init(document.getElementById('topology'))
      let nodes = this.formatData(orgList, peerList)
      let links = this.getLinks(orgList, peerList)

      let chartOption = {
        series: [
          {
            type: 'graph',
            layout: 'force',
            // draggable: true,
            label: {
              position: 'bottom',
              // distance: 0,
              show: true,
              fontWeight: 500,
              color: 'rgba(255,255,255,0.8)',
              fontFamily: 'DIN-Medium,DIN',
              fontSize: 18,
              lineHeight: 22,
            },
            roam: true,
            data: nodes,
            links: links,
            force: {
              repulsion: 3000,
              // layoutAnimation: false
            },
          },
        ],
      }

      this.topologyChart.setOption(chartOption)
    }

    // 点击切换通道显示通道列表
    changeChannelFn = () => {
      const { optionFlag } = this.state
      this.setState({
        optionFlag: !optionFlag,
      }, () => {
        this.refs.options.style.display = !optionFlag ? 'block' : 'none'
      })
    }

    // 切换通道
    changeChannel = (item) => {
      // 隐藏下拉框
      this.refs.options.style.display = 'none'

      const { channelList } = this.state
      let arr = channelList.filter(_item => _item.name === item.name)
      let channelId = arr.length && arr[0].id
      this.setState({
        channelId,
        currentChannel: item.name,
        optionFlag: false,
      }, () => {
        this.queryOverview()
        this.getRecentBlock()
        this.getRecentTx()
      })
    }

    // 获取通道列表
    getChannelList = async() => {
      const _this = this
      const { SocketModel } = this.props
      const { consortiumId, pageNum, pageSize } = this.state
      let data = null
      await getData().get(getChannelList.format({ consortiumId: consortiumId, pageNum: pageNum, pageSize })).then(res => {
        switch (res.status) {
        case 200:
          data = res.data.channels
          this.setState({
            channelList: data,
            currentChannel: data.length && data[0].name,
            channelId: data.length && data[0].id,
          }, () => {
            _this.queryOverview()
            _this.getRecentBlock()
            _this.getRecentTx()
            const { consortiumId, currentChannel } = this.state
            SocketModel.getSocket() && SocketModel.getSocket().emit('sub', 'block', {
              consortiumId,
              channelName: currentChannel,
            })
          })
          break
        default:
          message.error('请求失败')
          break
        }
      })
      return data
    }

    // 获取概览信息
    queryOverview = () => {
      const { consortiumId, channelId } = this.state
      const options = {
        consortiumId: consortiumId,
        channelId: channelId,
      }
      getData().get(queryOverview.format(options)).then(res => {
        if (res.status === 200) {
          const data = res.data
          // data.consortiumConf = 'Fabric';
          // data.createTime = moment(data.createTime).format('YYYY-MM-DD HH:mm:ss');
          data.network = 'Fabric' // 网络类型固定
          data.createTime = moment(data.createTime).format('YYYY-MM-DD HH:mm:ss')
          this.setState({
            resultData: res.data,
          })
        }
      })
    }

    getRecentBlock = () => {
      const { consortiumId, channelId, pageNum, pageSize } = this.state
      this.setState({
        bLoading: true,
      })
      getData().get(recentBlock.format({ consortiumId, channelId, pageNum, pageSize })).then(res => {
        if (res.status === 200) {
          let data = res.data.blocks || []
          data.length && data.map(item => {
            item.timestamp = moment(item.timestamp).format('MM.DD HH:mm:ss')
            return item
          })
          this.setState({
            table2Data: res.data.blocks || [],
          })
        }
      })
    }

    getRecentTx = () => {
      const { consortiumId, channelId, pageNum, pageSize } = this.state
      this.setState({
        tLoading: true,
      })
      getData().get(recentTx.format({ consortiumId, channelId, pageNum, pageSize })).then(res => {
        if (res.status === 200) {
          let data = res.data.transactions || []
          data.length && data.map((item, index) => {
            item.No = data.length - index
            item.timestamp = moment(item.timestamp).format('MM.DD HH:mm:ss')
            return item
          })

          this.setState({
            table1Data: data,
          })
        }
      })
    }

    // 数字轮播变化
    renderNumber = (data) => {
      if (!data && data !== 0) return
      return data.toString().split('').map((item, index) => {
        return (
          <div className="data-number-list" key={index}>
            <div className={`number-roll number-roll-${item}`}>
              <div className="number-item">0</div>
              <div className="number-item">1</div>
              <div className="number-item">2</div>
              <div className="number-item">3</div>
              <div className="number-item">4</div>
              <div className="number-item">5</div>
              <div className="number-item">6</div>
              <div className="number-item">7</div>
              <div className="number-item">8</div>
              <div className="number-item">9</div>
            </div>
          </div>

        )
      })
    }

    render() {
      const { currentChannel, channelList, data1Conf, data2Conf, resultData, table1Data, table2Data, channelId } = this.state
      return (
        <div id="monitor" className="monitor-page">
          <div className="header" id="monitor-header">
            <div className="to-dashboard" onClick={() => { this.props.history.go(-1) }}>
              <img src={require('../../images/monitor/goBack.svg')}/>
                        普通模式
            </div>
            <div className="change-channel">
              <div className="channel-selector">
                <div className="selector-item">{currentChannel}</div>
                <div className="suffix-dom" onClick={this.changeChannelFn}>切换通道<CaretDownOutlined/></div>
              </div>
              <div className="channel-options" ref="options">
                <div className="options-box" >
                  {
                    channelList.length && channelList.map((item) => {
                      const classNames = classnames({
                        'options-item': true,
                        'checked': item.id === channelId,
                      })
                      return (
                        <div key={item.id} onClick={() => { this.changeChannel(item) }} className={classNames}>{item.name}</div>
                      )
                    })
                  }
                </div>
              </div>
            </div>
          </div>
          <div className="monitor-body">
            <div className="data-box">
              <div className="data-total">
                {
                  data1Conf.length && data1Conf.map((element) => {
                    return (
                      <div key={element.params} className="data-item">
                        <span>{element.label}</span>
                        <span>{this.renderNumber(_.get(resultData, element.params))}</span>
                      </div>
                    )
                  })
                }
              </div>
              <div className="data-info">
                {
                  data2Conf.length && data2Conf.map((element) => {
                    return (
                      <div key={element.params} className="info-item">
                        <span>{element.label}</span>
                        {
                          element.params === 'consortiumStatus'
                            ? <span className={resultData && resultData[element.params]}>
                              {/* {resultData && STATUS[resultData[element.params]]} */}
                              <Badge status="processing" text={resultData && STATUS[resultData[element.params]]}/>
                            </span>
                            : <span>{resultData && resultData[element.params]}</span>
                        }

                      </div>
                    )
                  })
                }
              </div>
            </div>
            <div className="show-box">
              <div className="chain-info">
                <div className="chain-history chain-item">
                  <div className="box-title">本周交易历史</div>
                  <div id="echarts"></div>
                </div>
                <div className="chain-transaction chain-item">
                  <div className="box-title">最新交易</div>
                  <div className="transaction-table">
                    <Mtable data={table1Data} columns={column1}/>
                  </div>

                </div>
                <div className="chain-block chain-item">
                  <div className="box-title">最新区块</div>
                  <div className="block-table">
                    <Mtable data={table2Data} columns={column2} />
                  </div>

                </div>
              </div>
              <div className="chain-topology">
                <div className="box-title">拓扑图</div>
                <div id="topology" className="topology-body"></div>
              </div>
            </div>

          </div>

        </div>
      )
    }
}
export default Monitor
